﻿//using System.Linq;
//using UnityEngine.UIElements;
//using UnityEngine;
//using UnityEditor;
//using System;
//using System.IO;
//using System.Collections.Generic;
//using UnityEditor.Experimental.GraphView;
//using Newtonsoft.Json;
//using System.Reflection;
//using UnityEditor.UIElements;

//namespace SkillEditor
//{
//    public class SkillEditorGraphView : VisualElement
//    {
//        private RootNode root;

//        private string filePath;

//        public SkillEditorData data;
//        public int skillSpaceIndex;
//        public string[] skillSpaceIds;
//        public SkillSpace space => data.spaces[skillSpaceIndex];

//        public SkillEditorGraph graph;

//        public Dictionary<string, Type> dicTypes;

//        private SkillEditorSearchWindowProvider searchWindowProvider;

//        public string[] triggerLabels;
//        public int[] triggers;

//        public SkillEditorWindow window;

//        public GraphSubWindow subWindow;

//        public SkillEditorGraphView(SkillEditorWindow window) : base()
//        {
//            this.window = window;
//            style.flexGrow = 1;

//            triggers = new int[dicTriggers.Count];
//            triggerLabels = new string[dicTriggers.Count];
//            int index = 0;
//            foreach (var item in dicTriggers)
//            {
//                triggers[index] = item.Key;
//                triggerLabels[index] = item.Value;
//                index++;
//            }

//            //RegisterCallback<MouseDownEvent>(OnMouseDownEvent, TrickleDown.TrickleDown);
//            //RegisterCallback<ChangeDataEvent>(ChangeDataHandler, TrickleDown.TrickleDown);
//            RegisterCallback<ChangeDataEvent>(ChangeDataHandler, TrickleDown.NoTrickleDown);

//            subWindow = new GraphSubWindow();
//            Add(subWindow);

//            //RegisterCallback<FocusEvent>(FocusHandler);

//            //triggers = new int[] { 0, 100, 101, 102, 103, 104 };
//            //triggerLabels = new string[] { "", "人物初始化", "战斗开始时", "a", "c", "d" };

//            var toolbar = new IMGUIContainer(() =>
//            {
//                GUILayout.BeginHorizontal(EditorStyles.toolbar);

//                if (GUILayout.Button("New", EditorStyles.toolbarButton))
//                {
//                    FileCreate();
//                }
//                GUILayout.Space(6);
//                if (GUILayout.Button("Open", EditorStyles.toolbarButton))
//                {
//                    //if (saveRequested != null)
//                    FileOpen();
//                }
//                GUILayout.Space(6);
//                if (GUILayout.Button("Save", EditorStyles.toolbarButton))
//                {
//                    //if (saveRequested != null)
//                    FileSave();
//                }
//                GUILayout.Space(6);
//                if (GUILayout.Button("Save As...", EditorStyles.toolbarButton))
//                {
//                    FileSaveAs();
//                }
//                GUILayout.Space(6);
//                if (GUILayout.Button("Show In Project", EditorStyles.toolbarButton))
//                {
//                    ShowInProjectRequested();
//                }

//                GUILayout.Space(6);
//                if (GUILayout.Button("Eidt Node", EditorStyles.toolbarButton))
//                {
//                    SkillEditorNodeWindow.Open();
//                }

//                GUILayout.FlexibleSpace();

//                if (data != null)
//                {
//                    GUILayout.Label("Id:" + data.id);
//                    GUILayout.Space(4);

//                    if (GUILayout.Button("Parameter", EditorStyles.miniButton))
//                    {
//                        if (data != null)
//                            SkillEditorParameterWindow.Open().SetData(data);
//                    }

//                    GUILayout.Space(8);
//                    GUILayout.Label("Space:");
//                    int tempSkillSpaceIndex = EditorGUILayout.Popup(skillSpaceIndex, skillSpaceIds, GUILayout.Width(120f));
//                    if (tempSkillSpaceIndex != skillSpaceIndex)
//                    {
//                        skillSpaceIndex = tempSkillSpaceIndex;
//                        SetData(data);
//                    }
//                    GUILayout.Space(4);

//                    GUILayout.Label("Trigger:");
//                    space.trigger = EditorGUILayout.IntPopup(space.trigger, triggerLabels, triggers);

//                    GUILayout.Space(4);
//                    GUILayout.Label("Global:");
//                    space.global = GUILayout.Toggle(space.global == 1, "") ? 1 : 0;

//                    GUILayout.Space(4);

//                    if (GUILayout.Button("New Space", EditorStyles.miniButton))
//                    {
//                        List<SkillSpace> list = new List<SkillSpace>(data.spaces);
//                        list.Add(new SkillSpace());
//                        list[list.Count - 1].id = "Space" + list.Count;
//                        data.spaces = list.ToArray();
//                        skillSpaceIndex = list.Count - 1;
//                        SetData(data);
//                    }
//                    GUILayout.Space(4);
//                    if (GUILayout.Button("Del Space", EditorStyles.miniButton))
//                    {
//                        List<SkillSpace> list = new List<SkillSpace>(data.spaces);
//                        list.RemoveAt(skillSpaceIndex);
//                        data.spaces = list.ToArray();
//                        skillSpaceIndex = 0;
//                        SetData(data);
//                    }
//                }

//                GUILayout.EndHorizontal();
//            });
//            Add(toolbar);

//            //var toolbar2 = new IMGUIContainer(() =>
//            //{
//            //    GUILayout.BeginVertical(EditorStyles.inspectorDefaultMargins);
//            //    GUILayout.Label("Node:");
//            //    GUILayout.TextArea("Node:dasdasd\ndersdr\nsdfsdfsdfsdfsd\nsdfsdfsf\n");

//            //    GUILayout.EndVertical();
//            //});
//            //Add(toolbar2);

//            //VisualElement graphElement = new VisualElement();
//            //graphElement.style.flexGrow = 1;
//            //graphElement.style.maxHeight = 200;
//            //graphElement.style.maxWidth = 100;
//            //graphElement.style.width = 100;
//            //graphElement.style.paddingLeft = 5;
//            //graphElement.style.paddingRight = 5;
//            //graphElement.style.borderBottomColor = new Color(1f, 1f, 0f);
//            //Add(graphElement);

//            dicTypes = new Dictionary<string, Type>();
//            foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
//            {
//                foreach (Type type in assembly.GetTypes())
//                {
//                    TitleAttribute titleAttribute = type.GetCustomAttribute<TitleAttribute>();

//                    if (titleAttribute != null)
//                    {
//                        dicTypes[titleAttribute.title[titleAttribute.title.Length - 1]] = type;
//                    }
//                }
//            }

//            searchWindowProvider = new SkillEditorSearchWindowProvider();
//            searchWindowProvider.Initialize(window, CreateNewNode);
//        }

//        private void OnMouseDownEvent(MouseEventBase<MouseDownEvent> evt)
//        {
//            Debug.Log("Receiving " + evt + " in " + evt.propagationPhase + " for target " + evt.target);
//        }

//        protected override void ExecuteDefaultActionAtTarget(EventBase evt)
//        {
//            base.ExecuteDefaultActionAtTarget(evt);
//            //Debug.Log(evt + " " + evt.target);
//        }

//        protected override void ExecuteDefaultAction(EventBase evt)
//        {
//            base.ExecuteDefaultAction(evt);

//            //Debug.Log(evt);
//            if (evt is PointerEnterEvent)
//            {
//                //Debug.Log(evt.currentTarget);
//                if (evt.target is SampleNode sampleNode)
//                {
//                    subWindow.SetText(sampleNode.GetDesc());
//                }
//            }
//        }

//        public override void HandleEvent(EventBase evt)
//        {
//            base.HandleEvent(evt);
//            //Debug.Log(evt);
//        }

//        private void ChangeDataHandler(ChangeDataEvent evt)
//        {
//            Debug.Log(">>>> ChangeDataHandler");
//            subWindow.SetText(evt.data.GetDesc());
//        }

//        public static string GuidTo16String()
//        {
//            long i = 1;
//            foreach (byte b in Guid.NewGuid().ToByteArray())
//                i *= ((int)b + 1);
//            return string.Format("{0:x}", i - DateTime.Now.Ticks);
//        }

//        private Node CreateNewNode(string type)
//        {
//            SkillNode skillNode = new SkillNode();
//            //skillNode.id = Guid.NewGuid().ToString("N");
//            skillNode.id = GuidTo16String();
//            skillNode.type = type;
//            Node node = AddNode(skillNode);

//            //Vector2 p = window.rootVisualElement.WorldToLocal(Event.current.mousePosition);
//            //p = this.WorldToLocal(p);
//            //p = graph.WorldToLocal(p);
//            //node.SetPosition(new Rect(p, new Vector2()));
//            return node;
//        }

//        private Node AddNode(SkillNode skillNode)
//        {
//            Type type = dicTypes[skillNode.type];
//            SampleNode node = Activator.CreateInstance(type) as SampleNode;
//            node.SetData(space, skillNode);

//            graph.AddElement(node);

//            //node.RegisterCallback<ChangeDataEvent>(ChangeDataHandler);
//            //node.SendEvent(new ChangeDataEvent() { data = node });
//            //node.SendEvent

//            SendEvent(new ChangeDataEvent());

//            return node;
//        }

//        private void SetData(SkillEditorData v)
//        {
//            data = v;

//            for (int i = 0; i < data.spaces.Length; i++)
//            {
//                var skillSpace = data.spaces[i];

//                foreach (var skillAction in skillSpace.actions.Values)
//                {
//                    foreach (var item in skillAction.dataKey)
//                    {
//                        if (data.dataBool.ContainsKey(item.Value) && !skillSpace.dataBool.ContainsKey(item.Value))
//                        {
//                            skillSpace.dataBool.Add(item.Value, data.dataBool[item.Value]);
//                        }
//                        else if (data.dataEdge.ContainsKey(item.Value) && !skillSpace.dataEdge.ContainsKey(item.Value))
//                        {
//                            skillSpace.dataEdge.Add(item.Value, data.dataEdge[item.Value]);
//                        }
//                        else if (data.dataInt.ContainsKey(item.Value) && !skillSpace.dataInt.ContainsKey(item.Value))
//                        {
//                            skillSpace.dataInt.Add(item.Value, data.dataInt[item.Value]);
//                        }
//                        else if (data.dataString.ContainsKey(item.Value) && !skillSpace.dataString.ContainsKey(item.Value))
//                        {
//                            skillSpace.dataString.Add(item.Value, data.dataString[item.Value]);
//                        }
//                    }
//                }
//            }

//            skillSpaceIds = new string[data.spaces.Length];

//            for (int i = 0; i < data.spaces.Length; i++)
//            {
//                skillSpaceIds[i] = data.spaces[i].id;
//            }

//            if (skillSpaceIndex > data.spaces.Length)
//            {
//                skillSpaceIndex = 0;
//            }

//            if (graph != null)
//            {
//                graph.Clear();
//                Remove(graph);
//            }

//            graph = new SkillEditorGraph(searchWindowProvider);
//            Add(graph);
//            subWindow.BringToFront();

//            foreach (SkillNode item in space.actions.Values)
//            {
//                AddNode(item);
//            }

//            foreach (SkillNode node in space.actions.Values)
//            {
//                foreach (var dataKey in node.dataKey)
//                {
//                    SampleNode inNode = GetNode(node.id);
//                    Port inPort = inNode.GetPort(dataKey.Key);
//                    if (inPort == null)
//                        continue;

//                    if (inPort.portType == typeof(StructStep))
//                    {
//                        SampleNode outNode = GetNode(dataKey.Value);
//                        Port outPort = outNode.GetPort("Previous");
//                        graph.AddElement(outPort.ConnectTo(inPort));
//                    }
//                    else if (data.dataEdge.ContainsKey(dataKey.Value))
//                    {
//                        if (data.dataEdge[dataKey.Value] == node.id)
//                            continue;

//                        SampleNode outNode = GetNode(space.dataEdge[dataKey.Value]);

//                        foreach (var outDatakey in outNode.data.dataKey)
//                        {
//                            if (outDatakey.Value == dataKey.Value)
//                            {
//                                Port outPort = outNode.GetPort(outDatakey.Key);

//                                if (outPort != null)
//                                {
//                                    Debug.Log(string.Format("{0} connect {1} | {2}", dataKey.Key, outDatakey.Key, outDatakey.Key));

//                                    graph.AddElement(outPort.ConnectTo(inPort));
//                                }

//                                break;
//                            }
//                        }
//                    }
//                }
//            }
//        }

//        public SampleNode GetNode(string id)
//        {
//            var list = graph.graphElements.ToList();
//            foreach (var item in list)
//            {
//                if (item is SampleNode node && node.data.id == id)
//                {
//                    return node;
//                }
//            }
//            return null;
//        }

//        public Port GetPort(string nodeName, string portName)
//        {
//            var list = graph.ports.ToList();

//            for (int i = 0; i < list.Count; i++)
//            {
//                if (nodeName == list[i].node.name && portName == list[i].portName)
//                {
//                    return list[i];
//                }
//            }
//            return null;
//        }

//        private void FileCreate()
//        {
//            var newFilePath = EditorUtility.SaveFilePanel("Save Graph As...", "", "Skill.json", "json");
//            if (string.IsNullOrEmpty(newFilePath))
//                return;
//            filePath = newFilePath;
//            string fileName = Path.GetFileNameWithoutExtension(newFilePath);
//            SkillEditorData data = new SkillEditorData();
//            data.id = fileName;

//            data.spaces = new SkillSpace[1];
//            data.spaces[0] = new SkillSpace() { id = "Main" };
//            //data.spaces[0].nodes = new SkillNode[0];

//            File.WriteAllText(newFilePath, JsonConvert.SerializeObject(data, Formatting.Indented));

//            SetData(data);
//        }

//        private void FileOpen()
//        {
//            var newFilePath = EditorUtility.OpenFilePanel("Open...", "", "json");

//            if (string.IsNullOrEmpty(newFilePath))
//                return;
//            filePath = newFilePath;
//            string s = File.ReadAllText(newFilePath);

//            SkillEditorData data = JsonConvert.DeserializeObject<SkillEditorData>(s);

//            if (data.spaces == null || data.spaces.Length == 0)
//            {
//                data.spaces[0] = new SkillSpace() { id = "Main" };
//                //data.spaces[0].nodes = new SkillNode[0];
//            }
//            skillSpaceIndex = 0;

//            SetData(data);
//        }

//        private void ShowInProjectRequested()
//        {
//            throw new NotImplementedException();
//        }

//        private void FileSaveAs()
//        {
//            if (this.data == null)
//            {
//                FileCreate();
//                return;
//            }

//            var newFilePath = EditorUtility.SaveFilePanel("Save Graph As...", "", "Skill.json", "json");
//            if (string.IsNullOrEmpty(newFilePath))
//                return;
//            filePath = newFilePath;
//            string fileName = Path.GetFileNameWithoutExtension(newFilePath);
//            SkillEditorData data = this.data;
//            data.id = fileName;
//            File.WriteAllText(newFilePath, JsonConvert.SerializeObject(data, Formatting.Indented));
//            SetData(data);
//        }

//        private void FileSave()
//        {
//            var list = graph.graphElements.ToList();

//            //List<SkillNode> listNodes = new List<SkillNode>();

//            SkillSpace space = data.spaces[skillSpaceIndex];
//            space.dataBool.Clear();
//            space.dataInt.Clear();
//            space.dataString.Clear();
//            space.dataEdge.Clear();
//            space.actions.Clear();
//            space.beginAction = "";

//            for (int i = 0; i < list.Count; i++)
//            {
//                if (list[i] is SampleNode node)
//                {
//                    SkillNode skillNode = node.GetDataAndUpdate();
//                    space.actions.Add(skillNode.id, skillNode);

//                    if (skillNode.type == "Begin")
//                    {
//                        space.beginAction = skillNode.id;
//                    }
//                }
//            }

//            for (int i = 0; i < list.Count; i++)
//            {
//                if (list[i] is Edge edge)
//                {
//                    var inputNode = edge.input.node as SampleNode;
//                    var outputNode = edge.output.node as SampleNode;

//                    if (edge.input.portType == typeof(StructStep))
//                    {
//                        outputNode.data.dataKey[edge.output.portName] = inputNode.data.id;
//                        //space.dataEdge[outputNode.data.dataKey[edge.output.portName]] = outputNode.data.id;
//                    }
//                    else
//                    {
//                        inputNode.data.dataKey[edge.input.portName] = outputNode.data.dataKey[edge.output.portName];
//                        space.dataEdge[outputNode.data.dataKey[edge.output.portName]] = outputNode.data.id;
//                    }
//                }
//            }

//            data.dataInt.Clear();
//            data.dataBool.Clear();
//            data.dataEdge.Clear();
//            data.dataString.Clear();

//            for (int i = 0; i < data.spaces.Length; i++)
//            {
//                var skillSpace = data.spaces[i];

//                foreach (var item in skillSpace.dataInt)
//                {
//                    data.dataInt.Add(item.Key, item.Value);
//                }
//                foreach (var item in skillSpace.dataBool)
//                {
//                    data.dataBool.Add(item.Key, item.Value);
//                }
//                foreach (var item in skillSpace.dataEdge)
//                {
//                    data.dataEdge.Add(item.Key, item.Value);
//                }
//                foreach (var item in skillSpace.dataString)
//                {
//                    data.dataString.Add(item.Key, item.Value);
//                }
//            }

//            File.WriteAllText(filePath, JsonConvert.SerializeObject(data, Formatting.Indented));
//        }

//        public void Execute()
//        {
//            var rootEdge = root.OutputPort.connections.FirstOrDefault();
//            if (rootEdge == null) return;

//            var currentNode = rootEdge.input.node as ProcessNode;

//            while (true)
//            {
//                currentNode.Execute();

//                var edge = currentNode.OutputPort.connections.FirstOrDefault();
//                if (edge == null) break;

//                currentNode = edge.input.node as ProcessNode;
//            }
//        }

//        public Dictionary<int, string> dicTriggers = new Dictionary<int, string>() {
//            {1,"人物初始化" },
//            {2,"战斗准备时" },
//            {3,"战斗开始" },
//            {4,"血量为0时" },
//            {5,"死亡时" },
//            {6,"受到控制时" },
//            {7,"更换目标时" },
//            {8,"满蓝时" },
//            {9,"击杀时" },
//            {10,"检测释放" },
//            {11,"位置变动时" },

//            {101,"对目标造成伤害计算前" },
//             {102,"对目标造成伤害前" },
//              {103,"对目标伤害扣血前" },
//              {104,"对目标造成伤害后" },

//              {111,"对目标造成治疗计算前" },
//             {112,"对目标造成治疗前" },
//              {113,"对目标加血前" },
//              {114,"对目标造成治疗后" },

//              {201,"受到伤害计算前" },
//               {202,"受到伤害前" },
//              {203,"受到伤害扣血前" },
//              {204,"受到伤害后" },

//              {211,"受到治疗计算前" },
//               {212,"受到治疗前" },
//              {213,"受到治疗加血前" },
//              {214,"受到治疗后" },

//               {301,"技能释放时" },
//               {302,"技能开始时" },
//                {303,"技能引导触发时" },
//                 {304,"技能引导结束时" },
//                 {305,"技能打断时" },

//                  {401,"Buff造成伤害时" },
//                  {402,"Buff添加时" },
//                  {403,"Buff移除时" },
//                  {404,"Buff叠满时" },

//                   {501,"护盾创建时" },
//                   {502,"护盾添加时" },
//                    {503,"护盾移除时" },
//                     {504,"护盾消耗完时" },
//        };
//    }

//    public class GraphSubWindow : GraphElement
//    {
//        public virtual string styleName => "GraphSubWindow";

//        public Label label;

//        public GraphSubWindow()
//        {
//            //var styleSheet = Resources.Load<StyleSheet>($"Styles/{styleName}");
//            // Setup VisualElement from Stylesheet and UXML file
//            //styleSheets.Add(styleSheet);
//            style.position = Position.Absolute;
//            style.borderLeftWidth = 1;
//            style.borderTopWidth = 1;
//            style.borderRightWidth = 1;
//            style.borderBottomWidth = 1;
//            style.borderBottomLeftRadius = 5;
//            style.borderBottomRightRadius = 5;
//            style.borderTopLeftRadius = 5;
//            style.borderTopRightRadius = 5;
//            style.flexDirection = FlexDirection.Column;
//            style.minWidth = 100;
//            style.minHeight = 100;
//            style.width = 200;
//            style.height = 200;
//            style.backgroundColor = new Color(0.8274511f, 0.8274511f, 0.8274511f);

//            SetPosition(new Rect(0f, 20f, 200f, 200f));
//            label = new Label("C# Label");
//            label.AddToClassList("some-styled-label");
//            label.style.color = Color.black;
//            label.style.whiteSpace = WhiteSpace.Normal;
//            label.style.flexWrap = Wrap.Wrap;
//            contentContainer.Add(label);
//        }

//        public void SetText(string v)
//        {
//            Debug.Log("AAAAAA:" + v);
//            label.text = v;
//        }
//    }
//}